import re
from django.contrib.auth import authenticate, get_user_model
from django.contrib.auth.models import update_last_login
from rest_framework import serializers
from rest_framework_simplejwt.settings import api_settings
from rest_framework_simplejwt.serializers import TokenObtainSerializer
from rest_framework_simplejwt.tokens import RefreshToken
from utils.crypto_tool import myAESCipher, myDESCipher

User = get_user_model()


class RegisterCodeSerializer(serializers.Serializer):
    """
    注册验证码序列化器
    用于验证手机号码格式
    """
    mobile = serializers.CharField(max_length=11, label='手机号码')

    def validate_mobile(self, mobile):
        """验证手机号码格式"""
        # 检查长度
        if len(mobile) != 11:
            raise serializers.ValidationError('手机号码长度必须为11位！')

        # 使用正则表达式校验手机号码格式
        pattern = r'^1[3-9]\d{9}$'
        if not re.match(pattern, mobile):
            raise serializers.ValidationError('手机号码格式不正确，请重新输入！')
        return mobile


class RegisterSerializer(serializers.Serializer):
    """
    用户注册序列化器
    处理用户注册时的数据验证和处理
    """
    user_type = serializers.ChoiceField(choices=[
        ('TESTER', '测试员'),
        ('DEVELOPER', '开发人员'),
        ('MANAGER', '测试管理员'),
        ('VIEWER', '报告查看者'),
    ], label='用户类型', help_text="用户类型(TESTER、DEVELOPER、MANAGER、VIEWER)")
    username = serializers.CharField(max_length=30, label='用户名')
    password = serializers.CharField(min_length=6, label='密码', help_text='密码(需用AES加密)，6位及以上')
    phone_number = serializers.CharField(max_length=11, label='手机号码')
    code = serializers.CharField(min_length=4, max_length=4, label='验证码', help_text='4位验证码')
    email = serializers.EmailField(label="邮箱地址")

    def validate_phone_number(self, phone_number):
        """验证手机号码格式"""
        # 检查长度
        if len(phone_number) != 11:
            raise serializers.ValidationError('手机号码长度必须为11位！')

        # 使用正则表达式校验手机号码格式
        pattern = r'^1[3-9]\d{9}$'
        if not re.match(pattern, phone_number):
            raise serializers.ValidationError('手机号码格式不正确，请重新输入！')
        return phone_number

    def validate_code(self, code):
        """验证验证码格式"""
        # 确保验证码是4位数字
        if len(code) != 4 or not code.isdigit():
            raise serializers.ValidationError('验证码必须为4位数字！')
        return code

    def validate_password(self, password):
        """验证并解密密码"""
        try:
            decrypted_password = myAESCipher.decrypt(password)
        except Exception as e:
            raise serializers.ValidationError('密码格式错误')

        # 验证解密后的密码长度是否大于等于6
        if len(decrypted_password) < 6:
            raise serializers.ValidationError('密码长度必须大于等于6！')
        return decrypted_password

    def validate_user_type(self, user_type):
        """验证用户类型"""
        user_type = user_type.upper()
        # 注册时不允许选择ADMIN
        allowed_types = ['TESTER', 'DEVELOPER', 'MANAGER', 'VIEWER']
        if user_type not in allowed_types:
            raise serializers.ValidationError(f'注册时用户类型只能是以下之一: {", ".join(allowed_types)}')
        return user_type



class UserSerializer(serializers.ModelSerializer):
    """
    用户信息序列化器
    用于用户信息的序列化和反序列化
    """
    department_name = serializers.CharField(source='department.name', read_only=True)
    avatar = serializers.CharField(required=False, allow_blank=True)
    nickname = serializers.SerializerMethodField()
    
    class Meta:
        model = User
        fields = ['id', 'username', 'first_name', 'last_name', 'nickname', 'email', 'phone_number', 'user_type', 
                  'department', 'department_name', 'employee_id', 'avatar', 'date_joined',
                  'last_login', 'is_active', 'tests_created', 'tests_executed']
        read_only_fields = ['id', 'date_joined', 'last_login']
    
    def get_nickname(self, obj):
        """获取用户昵称（first_name + last_name）"""
        if obj.first_name or obj.last_name:
            return f"{obj.first_name or ''}{obj.last_name or ''}".strip()
        return obj.username


class LoginTokenObtainSerializer(TokenObtainSerializer):
    """
    登录token获取序列化器
    处理用户登录验证和token生成
    """
    token_class = RefreshToken
    code = serializers.CharField(max_length=4, min_length=4, label='验证码')
    uuid = serializers.UUIDField(label='验证码UUID')

    def validate(self, attrs):
        """验证登录信息并生成token"""
        data = {}

        # 对密码进行解密后再做校验
        try:
            attrs['password'] = myDESCipher.decrypt(attrs['password'])
        except Exception as e:
            raise serializers.ValidationError("密码解密失败")
        
        # 校验用户是否存在（校验用户是否是活跃状态，是否是激活）
        user = authenticate(username=attrs['username'], password=attrs['password'])
        
        # 生成token
        if user:
            refresh = self.get_token(user)
            data["access"] = str(refresh.access_token)
            data['user'] = user
            
            # 手动更新最后登录时间
            from django.utils import timezone
            user.last_login = timezone.now()
            user.save(update_fields=['last_login'])
        
        return data
